/**
 * 数据缓存系统
 * 支持内存缓存和本地存储缓存
 */

import { log } from './logger'

// 缓存项接口
interface CacheItem<T = any> {
  data: T
  timestamp: number
  ttl: number // 生存时间（毫秒）
  key: string
}

// 缓存配置
interface CacheConfig {
  defaultTTL: number // 默认缓存时间（毫秒）
  maxSize: number // 最大缓存项数量
  storage: 'memory' | 'localStorage' | 'sessionStorage'
}

// 缓存管理器
class CacheManager {
  private memoryCache = new Map<string, CacheItem>()
  private config: CacheConfig

  constructor(config: Partial<CacheConfig> = {}) {
    this.config = {
      defaultTTL: 5 * 60 * 1000, // 默认5分钟
      maxSize: 100,
      storage: 'memory',
      ...config
    }
  }

  // 生成缓存键
  private generateKey(prefix: string, params?: Record<string, any>): string {
    if (!params) return prefix
    
    const sortedParams = Object.keys(params)
      .sort()
      .reduce((result, key) => {
        result[key] = params[key]
        return result
      }, {} as Record<string, any>)
    
    return `${prefix}:${JSON.stringify(sortedParams)}`
  }

  // 检查缓存项是否过期
  private isExpired(item: CacheItem): boolean {
    return Date.now() - item.timestamp > item.ttl
  }

  // 清理过期缓存
  private cleanExpired() {
    if (this.config.storage === 'memory') {
      for (const [key, item] of this.memoryCache.entries()) {
        if (this.isExpired(item)) {
          this.memoryCache.delete(key)
          log.debug('清理过期缓存', { key }, 'Cache')
        }
      }
    }
  }

  // 限制缓存大小
  private limitSize() {
    if (this.config.storage === 'memory' && this.memoryCache.size > this.config.maxSize) {
      // 删除最旧的缓存项
      const entries = Array.from(this.memoryCache.entries())
      entries.sort((a, b) => a[1].timestamp - b[1].timestamp)
      
      const toDelete = entries.slice(0, entries.length - this.config.maxSize)
      toDelete.forEach(([key]) => {
        this.memoryCache.delete(key)
        log.debug('删除旧缓存项', { key }, 'Cache')
      })
    }
  }

  // 从存储中获取缓存
  private getFromStorage(key: string): CacheItem | null {
    try {
      let storage: Storage
      
      switch (this.config.storage) {
        case 'localStorage':
          storage = localStorage
          break
        case 'sessionStorage':
          storage = sessionStorage
          break
        case 'memory':
        default:
          return this.memoryCache.get(key) || null
      }

      const item = storage.getItem(key)
      if (!item) return null

      const cacheItem: CacheItem = JSON.parse(item)
      
      if (this.isExpired(cacheItem)) {
        storage.removeItem(key)
        return null
      }

      return cacheItem
    } catch (error) {
      log.error('获取缓存失败', error, 'Cache')
      return null
    }
  }

  // 保存到存储
  private saveToStorage(key: string, item: CacheItem) {
    try {
      switch (this.config.storage) {
        case 'localStorage':
          localStorage.setItem(key, JSON.stringify(item))
          break
        case 'sessionStorage':
          sessionStorage.setItem(key, JSON.stringify(item))
          break
        case 'memory':
        default:
          this.memoryCache.set(key, item)
          this.limitSize()
          break
      }
    } catch (error) {
      log.error('保存缓存失败', error, 'Cache')
    }
  }

  // 设置缓存
  set<T>(prefix: string, data: T, params?: Record<string, any>, ttl?: number): void {
    const key = this.generateKey(prefix, params)
    const item: CacheItem<T> = {
      data,
      timestamp: Date.now(),
      ttl: ttl || this.config.defaultTTL,
      key
    }

    this.saveToStorage(key, item)
    log.debug('设置缓存', { key, ttl: item.ttl }, 'Cache')
  }

  // 获取缓存
  get<T>(prefix: string, params?: Record<string, any>): T | null {
    const key = this.generateKey(prefix, params)
    const item = this.getFromStorage(key)

    if (!item) {
      log.debug('缓存未命中', { key }, 'Cache')
      return null
    }

    log.debug('缓存命中', { key }, 'Cache')
    return item.data as T
  }

  // 删除缓存
  delete(prefix: string, params?: Record<string, any>): void {
    const key = this.generateKey(prefix, params)
    
    switch (this.config.storage) {
      case 'localStorage':
        localStorage.removeItem(key)
        break
      case 'sessionStorage':
        sessionStorage.removeItem(key)
        break
      case 'memory':
      default:
        this.memoryCache.delete(key)
        break
    }

    log.debug('删除缓存', { key }, 'Cache')
  }

  // 清空所有缓存
  clear(): void {
    switch (this.config.storage) {
      case 'localStorage':
        localStorage.clear()
        break
      case 'sessionStorage':
        sessionStorage.clear()
        break
      case 'memory':
      default:
        this.memoryCache.clear()
        break
    }

    log.info('清空所有缓存', undefined, 'Cache')
  }

  // 清空指定前缀的缓存
  clearByPrefix(prefix: string): void {
    switch (this.config.storage) {
      case 'localStorage':
      case 'sessionStorage':
        const storage = this.config.storage === 'localStorage' ? localStorage : sessionStorage
        const keysToDelete: string[] = []
        
        for (let i = 0; i < storage.length; i++) {
          const key = storage.key(i)
          if (key && key.startsWith(prefix)) {
            keysToDelete.push(key)
          }
        }
        
        keysToDelete.forEach(key => storage.removeItem(key))
        break
        
      case 'memory':
      default:
        for (const key of this.memoryCache.keys()) {
          if (key.startsWith(prefix)) {
            this.memoryCache.delete(key)
          }
        }
        break
    }

    log.debug('清空前缀缓存', { prefix }, 'Cache')
  }

  // 获取缓存统计信息
  getStats() {
    let size = 0
    let expiredCount = 0

    if (this.config.storage === 'memory') {
      size = this.memoryCache.size
      for (const item of this.memoryCache.values()) {
        if (this.isExpired(item)) {
          expiredCount++
        }
      }
    }

    return {
      size,
      expiredCount,
      maxSize: this.config.maxSize,
      storage: this.config.storage
    }
  }

  // 定期清理过期缓存
  startCleanupTimer(interval = 60000) { // 默认1分钟清理一次
    setInterval(() => {
      this.cleanExpired()
    }, interval)
  }
}

// 创建不同类型的缓存实例
export const memoryCache = new CacheManager({
  storage: 'memory',
  defaultTTL: 5 * 60 * 1000, // 5分钟
  maxSize: 100
})

export const sessionCache = new CacheManager({
  storage: 'sessionStorage',
  defaultTTL: 30 * 60 * 1000, // 30分钟
  maxSize: 50
})

export const persistentCache = new CacheManager({
  storage: 'localStorage',
  defaultTTL: 24 * 60 * 60 * 1000, // 24小时
  maxSize: 200
})

// 启动清理定时器
memoryCache.startCleanupTimer()

// 缓存键常量
export const CACHE_KEYS = {
  LESSONS: 'lessons',
  LESSON_DETAIL: 'lesson_detail',
  CATEGORIES: 'categories',
  CATEGORY_TREE: 'category_tree',
  TAGS: 'tags',
  USER_PROFILE: 'user_profile',
  UPLOAD_FILES: 'upload_files'
} as const

export default CacheManager 